﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Web;
using Pampa.Grid.Core.Filters;
using Pampa.MVC.Fluent.Common;

namespace Pampa.MVC.Fluent.Grid
{
    public class FilterModifierBuilder<T> : AbstractBuilder, IHtmlString 
    {
        private readonly CustomGridBuilder<T> _gridBuilder;
        private readonly FilterBuilder _filterBuilder;

        public FilterModifierBuilder(CustomGridBuilder<T> gridBuilder, FilterBuilder filterBuilder)
        {
            _gridBuilder = gridBuilder;
            _filterBuilder = filterBuilder;
        }

        #region Or Functions

        // (all previous filters) or this
        public FilterStringBuilder<T> Or(Expression<Func<T, string>> property)
        {
            var orGroupFilter = _filterBuilder.Or();
            return new FilterStringBuilder<T>(_gridBuilder, orGroupFilter, property);
        }

        public FilterNonStringBuilder<T, int> Or(Expression<Func<T, int>> property)
        {
            var orGroupFilter = _filterBuilder.Or();
            return new FilterNonStringBuilder<T, int>(_gridBuilder, orGroupFilter, property);
        }

        public FilterNonStringBuilder<T, int?> Or(Expression<Func<T, int?>> property)
        {
            var orGroupFilter = _filterBuilder.Or();
            return new FilterNonStringBuilder<T, int?>(_gridBuilder, orGroupFilter, property);
        }

        public FilterNonStringBuilder<T, Single> Or(Expression<Func<T, Single>> property)
        {
            var orGroupFilter = _filterBuilder.Or();
            return new FilterNonStringBuilder<T, Single>(_gridBuilder, orGroupFilter, property);
        }

        public FilterNonStringBuilder<T, Single?> Or(Expression<Func<T, Single?>> property)
        {
            var orGroupFilter = _filterBuilder.Or();
            return new FilterNonStringBuilder<T, Single?>(_gridBuilder, orGroupFilter, property);
        }

        public FilterNonStringBuilder<T, Double> Or(Expression<Func<T, Double>> property)
        {
            var orGroupFilter = _filterBuilder.Or();
            return new FilterNonStringBuilder<T, Double>(_gridBuilder, orGroupFilter, property);
        }

        public FilterNonStringBuilder<T, Double?> Or(Expression<Func<T, Double?>> property)
        {
            var orGroupFilter = _filterBuilder.Or();
            return new FilterNonStringBuilder<T, Double?>(_gridBuilder, orGroupFilter, property);
        }

        public FilterNonStringBuilder<T, Decimal> Or(Expression<Func<T, Decimal>> property)
        {
            var orGroupFilter = _filterBuilder.Or();
            return new FilterNonStringBuilder<T, Decimal>(_gridBuilder, orGroupFilter, property);
        }

        public FilterNonStringBuilder<T, Decimal?> Or(Expression<Func<T, Decimal?>> property)
        {
            var orGroupFilter = _filterBuilder.Or();
            return new FilterNonStringBuilder<T, Decimal?>(_gridBuilder, orGroupFilter, property);
        }

        public FilterNonStringBuilder<T, DateTime> Or(Expression<Func<T, DateTime>> property)
        {
            var orGroupFilter = _filterBuilder.Or();
            return new FilterNonStringBuilder<T, DateTime>(_gridBuilder, orGroupFilter, property);
        }

        public FilterNonStringBuilder<T, DateTime?> Or(Expression<Func<T, DateTime?>> property)
        {
            var orGroupFilter = _filterBuilder.Or();
            return new FilterNonStringBuilder<T, DateTime?>(_gridBuilder, orGroupFilter, property);
        }

        public FilterUnknownTypeBuilder<T, TEntity> Or<TEntity>(Expression<Func<T, TEntity>> property)
        {
            var orGroupFilter = _filterBuilder.Or();
            return new FilterUnknownTypeBuilder<T, TEntity>(_gridBuilder, orGroupFilter, property);
        }

        #endregion

        #region And Functions

        // (all previous filters) and this
        public FilterStringBuilder<T> And(Expression<Func<T, string>> property)
        {
            var andGroupFilter = _filterBuilder.And();
            return new FilterStringBuilder<T>(_gridBuilder, andGroupFilter, property);
        }

        public FilterNonStringBuilder<T, int> And(Expression<Func<T, int>> property)
        {
            var andGroupFilter = _filterBuilder.And();
            return new FilterNonStringBuilder<T, int>(_gridBuilder, andGroupFilter, property);
        }

        public FilterNonStringBuilder<T, int?> And(Expression<Func<T, int?>> property)
        {
            var andGroupFilter = _filterBuilder.And();
            return new FilterNonStringBuilder<T, int?>(_gridBuilder, andGroupFilter, property);
        }

        public FilterNonStringBuilder<T, Single> And(Expression<Func<T, Single>> property)
        {
            var andGroupFilter = _filterBuilder.And();
            return new FilterNonStringBuilder<T, Single>(_gridBuilder, andGroupFilter, property);
        }

        public FilterNonStringBuilder<T, Single?> And(Expression<Func<T, Single?>> property)
        {
            var andGroupFilter = _filterBuilder.And();
            return new FilterNonStringBuilder<T, Single?>(_gridBuilder, andGroupFilter, property);
        }

        public FilterNonStringBuilder<T, Double> And(Expression<Func<T, Double>> property)
        {
            var andGroupFilter = _filterBuilder.And();
            return new FilterNonStringBuilder<T, Double>(_gridBuilder, andGroupFilter, property);
        }

        public FilterNonStringBuilder<T, Double?> And(Expression<Func<T, Double?>> property)
        {
            var andGroupFilter = _filterBuilder.And();
            return new FilterNonStringBuilder<T, Double?>(_gridBuilder, andGroupFilter, property);
        }

        public FilterNonStringBuilder<T, Decimal> And(Expression<Func<T, Decimal>> property)
        {
            var andGroupFilter = _filterBuilder.And();
            return new FilterNonStringBuilder<T, Decimal>(_gridBuilder, andGroupFilter, property);
        }

        public FilterNonStringBuilder<T, Decimal?> And(Expression<Func<T, Decimal?>> property)
        {
            var andGroupFilter = _filterBuilder.And();
            return new FilterNonStringBuilder<T, Decimal?>(_gridBuilder, andGroupFilter, property);
        }

        public FilterNonStringBuilder<T, DateTime> And(Expression<Func<T, DateTime>> property)
        {
            var andGroupFilter = _filterBuilder.And();
            return new FilterNonStringBuilder<T, DateTime>(_gridBuilder, andGroupFilter, property);
        }

        public FilterNonStringBuilder<T, DateTime?> And(Expression<Func<T, DateTime?>> property)
        {
            var andGroupFilter = _filterBuilder.And();
            return new FilterNonStringBuilder<T, DateTime?>(_gridBuilder, andGroupFilter, property);
        }

        public FilterUnknownTypeBuilder<T, TEntity> And<TEntity>(Expression<Func<T, TEntity>> property)
        {
            var andGroupFilter = _filterBuilder.And();
            return new FilterUnknownTypeBuilder<T, TEntity>(_gridBuilder, andGroupFilter, property);
        }
        
        #endregion

        public string ToHtmlString()
        {
            return _gridBuilder.ToHtmlString();
        }
    }
}
